<template>
  <div class="region-select clearfix">
    <template v-for="(item,index) in selectInputList">
      <el-select filterable clearable :key="item.type" v-model="item.code" :size="size" :placeholder="item.placeholder"
        :loading="loading" @change="itemChange(item,index)">
        <el-option v-for="dropdown in item.dropdownList" :key="dropdown.code" :value="dropdown.code" :label="dropdown.name">
        </el-option>
      </el-select>
    </template>
  </div>
</template>

<script>
  import CommonApi from 'services/commonApi';

  export default {
    props: {
      value: {
        type: Array,
        required: true
      },
      size: String,
      count: {
        type: Number,
        default: 5
      }
    },

    data() {
      return {
        loading: false,
        selectInputList: [],
        typeList: ['province', 'city', 'area', 'street', 'village']
      };
    },

    created() {
      this.initData();
      this.initDropdownData();
    },

    methods: {
      initData() {
        let value = this.value;
        let count = this.count;
        let typeList = this.typeList;
        let selectInputList = [];
        for (let i = 0; i < count; i++) {
          let type = typeList[i];
          let code = value[i];
          if (code === undefined) {
            code = '';
          }
          selectInputList.push({
            code,
            type,
            placeholder: this.i18n.getMsg(`common.regionSelect.${type}`),
            dropdownList: []
          });
        }
        this.selectInputList = selectInputList;
      },

      initDropdownData() {
        let selectInputList = this.selectInputList;
        let promiseList = [
          this.setProvinceList(selectInputList[0])
        ];

        if (this.value.length !== 0) {
          for (let i = 1; i < selectInputList.length; i++) {
            const item = selectInputList[i];
            let code = selectInputList[i - 1].code;
            let type = item.type;
            if (type === 'city') {
              promiseList.push(this.setCityList(item, code, false));
            } else if (type === 'area') {
              promiseList.push(this.setAreaList(item, code, false));
            } else if (type === 'street') {
              promiseList.push(this.setStreetList(item, code, false));
            } else if (type === 'village') {
              promiseList.push(this.setVillageList(item, code, false));
            }
          }
        }

        this.loading = true;
        Promise.all(promiseList).then(() => {
          this.loading = false;
        }).catch(() => {
          this.loading = false;
        });
      },

      itemChange(item, index) {
        if (this.count <= index + 1) {
          this.toChange();
          return;
        }

        let selectInputList = this.selectInputList;
        let nextItem = selectInputList[index + 1];
        let type = nextItem.type;
        let promiseList = [];
        if (type === 'city') {
          promiseList.push(this.setCityList(nextItem, item.code));
        } else if (type === 'area') {
          promiseList.push(this.setAreaList(nextItem, item.code));
        } else if (type === 'street') {
          promiseList.push(this.setStreetList(nextItem, item.code));
        } else if (type === 'village') {
          promiseList.push(this.setVillageList(nextItem, item.code));
        }

        this.loading = true;
        Promise.all(promiseList).then(() => {
          this.toChange();
          this.clearDropdown(index + 2);
          this.loading = false;
        }).catch(() => {
          this.loading = false;
        });
      },

      setProvinceList(item) {
        return CommonApi.getProvinceList().then(provinceList => {
          item.dropdownList = provinceList;
          return provinceList;
        });
      },

      setCityList(item, code, hasClear = true) {
        if (code === '') {
          item.code = '';
          item.dropdownList = [];
          return Promise.resolve([]);
        }

        return CommonApi.getCityList(code).then(cityList => {
          if (hasClear) {
            item.code = '';
          }
          item.dropdownList = cityList;
          return cityList;
        });
      },

      setAreaList(item, code,hasClear = true) {
        if (code === '') {
          item.code = '';
          item.dropdownList = [];
          return Promise.resolve([]);
        }

        return CommonApi.getAreaList(code).then(cityList => {
          if (hasClear) {
            item.code = '';
          }
          item.dropdownList = cityList;
          return cityList;
        });
      },

      setStreetList(item, code,hasClear = true) {
        if (code === '') {
          item.code = '';
          item.dropdownList = [];
          return Promise.resolve([]);
        }

        return CommonApi.getStreetList(code).then(cityList => {
          if (hasClear) {
            item.code = '';
          }
          item.dropdownList = cityList;
          return cityList;
        });
      },

      setVillageList(item, code,hasClear = true) {
        if (code === '') {
          item.code = '';
          item.dropdownList = [];
          return Promise.resolve([]);
        }

        return CommonApi.getVillageList(code).then(cityList => {
          if (hasClear) {
            item.code = '';
          }
          item.dropdownList = cityList;
          return cityList;
        });
      },

      clearDropdown(index) {
        let selectInputList = this.selectInputList;
        for (let i = index; i < selectInputList.length; i++) {
          const item = selectInputList[i];
          item.code = '';
          item.dropdownList = [];
        }
      },

      toChange() {
        let selectInputList = this.selectInputList;
        let codeList = [];
        for (let i = 0; i < selectInputList.length; i++) {
          const item = selectInputList[i];
          let code = item.code;
          if (code !== '') {
            codeList.push(code);
          } else {
            break;
          }
        }

        this.$emit('input', codeList);
        this.$emit('change', codeList);
      }
    }
  };

</script>

<style lang="scss" scoped>
  .region-select {
    >.el-select {
      width: 160px;
      margin-right: 5px;
      margin-bottom: 5px;

      &:last-child {
        margin-right: 0;
      }
    }
  }

</style>
